home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
smaltalk
/
st80_pr4.lha
/
st80_pre4
/
latex.st
(
.txt
)
< prev
Wrap
LaTeX Document
|
1993-07-24
|
12KB
|
334 lines
" NAME latex.st
AUTHOR mcconnel@cs.uiuc.edu
FUNCTION print out ST source as LaTeX source
ST-VERSIONS 2.5, 4.0
PREREQUISITES
CONFLICTS
DISTRIBUTION world
VERSION 1.0
DATE June 21, 1991
SUMMARY latex.st
This code causes the print-out menu item in the various browser panes
to produce LaTeX. Printing out categories and classes yields
self-contained LaTeX documents; printing out protocols and methods
yields LaTeX output suitable for inclusion in a LaTeX document. In
particular, printing a category yields a document with a table of
contents (showing what page the class definitions are on), and so you
will need to LaTeX the resulting file twice.
Carl McConnell
!Browser methodsFor: 'private-category functions'!
printOutCategory
organization printOutCategory: category! !
!Browser methodsFor: 'private-class functions'!
printOutClass
self selectedClass printOut! !
!Browser methodsFor: 'private-protocol functions'!
printOutProtocol
self selectedClass printOutCategory: protocol! !
!Browser methodsFor: 'private-selector functions'!
printOutMessage
self selectedClass printOutMessage: selector! !
!SystemOrganizer methodsFor: 'fileIn/Out'!
printOutCategory: category
LatexStream for: category do:
[:fileStream |
Transcript cr; show: 'Printing out ' , category , ':'; cr.
fileStream beginCategory: category.
self printOutCategory: category on: fileStream.
fileStream endCategory]!
printOutCategory: category on: aFileStream
| firstTrip |
firstTrip _ true.
(self superclassOrder: category)
do:
[:class |
"The test prevents a blank page from being printed right after
the table of contents."
firstTrip
ifTrue: [firstTrip _ false]
ifFalse: [aFileStream anotherClass].
Transcript tab; show: class name; cr.
class printOutOn: aFileStream]! !
!Filename methodsFor: 'stream creation'!
latexStream
"Answer a write stream connected to the file represented by
the receiver."
^LatexStream on: (FileConnection
openFileNamed: self
mode: #writeOnly
creationRule: #truncateOrCreate)! !
ExternalWriteStream subclass: #LatexStream
instanceVariableNames: 'inComment lastCharacter generateTableOfContents '
classVariableNames: 'CharacterMap '
poolDictionaries: ''
category: 'OS-Streaming'!
LatexStream comment:
'I translate Smalltalk into LaTeX.
Problems: tables in comments aren''t always correctly aligned.
Author:
Carl McConnell
mcconnel@cs.uiuc.edu
Department of Computer Science
University of Illinois at Urbana-Champaign
5/90'!
!LatexStream methodsFor: 'beginning-ending'!
beginCategory: category
self generateTableOfContents: true.
self beginDocument.
self line: '\title{{\bf ', category, '}}'.
self line: '\author{', self version, '}'.
self line: '\date{' , Date today printString , ' ' , Time now printString , '}'.
self line: '\maketitle'.
self line: '\pagenumbering{roman}'.
self line: '\setcounter{page}{1}'.
self line: '\tableofcontents'.
self line: '\clearpage'.
self line: '\pagenumbering{arabic}'.
self line: '\setcounter{page}{1}'.
self line: '%'!
beginClass
self beginDocument.
self line: '\begin{center}'.
self line: '{\tiny ', self version, '}'.
self line: '\end{center}'.
self blankLines: 3!
endCategory
self endDocument!
endClass
self endDocument! !
!LatexStream methodsFor: 'printing'!
printClassComment: aString
aString isEmpty ifTrue: [^self].
self blankLines: 1.
self beginFont: '\it'.
self printSmalltalkString: aString.
self endFont; cr!
printClassDefinitionFor: aString from: aTable
self line: '\begin{center}'.
self beginFont: '\Large \bf'.
self nextPutAll: aString.
self endFont; cr.
self line: '\end{center}'.
self blankLines: 3.
self line: '\markright{{\bf ' , aString , '} \hfill}'.
self generateTableOfContents ifTrue: [self line: '\addcontentsline{toc}{section}{' , aString , '}'].
self line: '\begin{tabular}{ll}'.
aTable do:
[:assoc |
self nextPutAll: assoc key.
self nextPutAll: ' & '.
assoc value isEmpty
ifTrue: [self beginFont: '\it'; nextPutAll: 'none'; endFont]
ifFalse: [self nextPutAll: '\parbox[t]{4.0in}{\raggedright '; beginFont: '\bf'; nextPutAll: assoc value; endFont; nextPut: $}].
assoc = aTable last
ifTrue: [self cr]
ifFalse: [self line: ' \\']].
self line: '\end{tabular}'!
printMethod: aSelector withBody: aString
self beginFont: '\bf'; printSmalltalkString: aSelector; endFont.
self cr; line: '\nopagebreak'.
self printSmalltalkString: aString.
self cr!
printProtocolHeader: aString
self beginFont: '\sl'.
self nextPutAll: 'Protocol for '; nextPutAll: aString.
self endFont; cr.
self line: '\nopagebreak'! !
!LatexStream methodsFor: 'separating'!
anotherClass
self line: '%'.
self line: '\clearpage'!
anotherMethod
self blankLines: 2!
anotherProtocol
self blankLines: 3! !
!LatexStream methodsFor: 'private miscellaneous'!
blankLines: n
self cr.
self nextPutAll: '\addvspace{'; print: n; nextPutAll: 'ex}'; cr.
self line: '\noindent'!
generateTableOfContents
^generateTableOfContents isNil ifTrue: [false] ifFalse: [generateTableOfContents]!
generateTableOfContents: aBoolean
generateTableOfContents _ aBoolean!
line: aString
self nextPutAll: aString; cr!
version
"The version name for Objectworks 4.0
contains a backslash, hence this hack."
^Smalltalk version copyReplaceAll: '\' with: '$\backslash$'! !
!LatexStream methodsFor: 'private printing'!
printSmalltalkString: aString
| output |
inComment _ false.
lastCharacter _ nil.
aString do:
[:aCharacter |
output _ CharacterMap at: aCharacter asciiValue.
output notNil
ifTrue: [self nextPutAll: output]
ifFalse: ["This character must require special handling."
self printSpecialCharacter: aCharacter].
lastCharacter _ aCharacter]!
printSpecialCharacter: aCharacter
aCharacter = $"
ifTrue:
[inComment
ifTrue: [self nextPutAll: ''''''; endFont]
ifFalse: [self beginFont: '\it'; nextPutAll: '``'].
inComment _ inComment not.
^self].
aCharacter = $=
ifTrue:
[self nextPutAll: (lastCharacter = $:
ifTrue: ['=']
ifFalse: ['$=$']).
^self]! !
!LatexStream methodsFor: 'private beginning-ending'!
beginDocument
self line: '\documentstyle[11pt]{report}'.
self line: '\oddsidemargin 0in \evensidemargin 0in'.
self line: '\marginparwidth 0in \marginparsep 0in'.
self line: '\topmargin 0in \topskip 0in'.
self line: '\headheight 0.25in \headsep 0.25in'.
self line: '\footheight 0in \footskip 0.25in'.
self line: '\textheight 8.25in \textwidth 6.5in'.
self line: '\raggedbottom \sloppy'.
self line: '\pagestyle{myheadings}'.
self line: '%'.
self line: '\begin{document}'!
beginFont: aString
self nextPut: ${.
self nextPutAll: aString; space!
endDocument
self line: '\end{document}'!
endFont
self nextPut: $}! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
LatexStream class
instanceVariableNames: ''!
!LatexStream class methodsFor: 'class initialization'!
at: aCharacter put: anObject
CharacterMap at: aCharacter asciiValue put: anObject.
^anObject!
createCharacterMap
CharacterMap _ Array new: 127.
1 to: 127 do: [:i | CharacterMap at: i put: (String with: (Character value: i))]!
initialize
"Initialize the table for mapping characters to LaTeX. Characters
for which special (or no) action is to be taken have nil entries. We
won't have to handle NUL characters, so the table size is 127."
| lineEndString first |
self createCharacterMap.
"These require special handling."
self at: $" put: nil.
self at: $= put: nil.
"We assume that we can distinguish the end-of-line string by its
first character; the rest we just ignore."
lineEndString _ self lineEndString.
first _ true.
lineEndString do: [:ch | self at: ch put: (first
ifTrue:
[first _ false.
'\\' , lineEndString]
ifFalse: [nil])].
self at: Character tab put: '\hspace*{4ex}'.
self at: $# put: '\#'.
self at: $$ put: '\$'.
self at: $% put: '\%'.
self at: $& put: '\&'.
self at: $_ put: '$\leftarrow$'.
self at: ${ put: '\{'.
self at: $} put: '\}'.
self at: $~ put: '{\char126}'.
self at: $^ put: '$\uparrow$'.
self at: $\ put: '$\backslash$'.
self at: $| put: '$|$'.
self at: $> put: '$>$'.
self at: $< put: '$<$'.
self at: $+ put: '$+$'.
self at: $- put: '$-$'!
lineEndString
"Return the end-of-line string."
| stream |
stream _ WriteStream on: (String new: 4).
stream cr.
^stream contents! !
!LatexStream class methodsFor: 'instance creation'!
for: aString do: aBlock
| fileName fileStream |
fileName _ Filename
request: 'Print LaTeX on'
initially: aString , '.tex'
shouldExist: nil.
fileName = '' ifTrue: [^nil].
fileStream _ (Filename named: fileName) latexStream.
[aBlock value: fileStream]
valueNowOrOnUnwindDo: [fileStream close]! !
LatexStream initialize!
!ClassDescription methodsFor: 'fileIn/Out'!
definitionAsTable
| table |
table _ OrderedCollection new.
table add: (Association key: 'class name' value: self name).
table add: (Association key: 'superclass' value: (superclass == nil
ifTrue: ['']
ifFalse: [superclass name])).
table add: (Association key: 'instance variable names' value: self instanceVariablesString).
table add: (Association key: 'class variable names' value: self classVariablesString).
table add: (Association key: 'pool dictionaries' value: self sharedPoolsString).
table add: (Association key: 'category' value: self category asString).
^table!
printOutCategory: aString
LatexStream for: self name , '-' , aString do: [:fileStream | self printOutCategory: aString on: fileStream]!
printOutCategory: aString on: aFileStream
self printOutCategoryChunk: aString on: aFileStream.
(self organization listAtCategoryNamed: aString)
do:
[:sel |
aFileStream anotherMethod.
self printOutMethodChunk: sel on: aFileStream]!
printOutCategoryChunk: aString on: aFileStream
aFileStream printProtocolHeader: aString!
printOutMessage: aString
LatexStream for: self name , '-' , aString do: [:fileStream | self printOutMethodChunk: aString on: fileStream]!
printOutMethodChunk: aSelector on: aFileStream
| string parser lastSelectorChar |
Cursor write
showWhile:
[string _ self sourceCodeAt: aSelector.
(parser _ self parserClass new) parseSelector: string.
lastSelectorChar _ parser endOfLastToken min: string size.
["The parser includes the line separator(s) as part of the selector.
Although I don't think it makes any difference in the printed output, I prefer
the line separator(s) to be part of the body, since it makes the LaTeX
look nicer; hence the loop."
(string at: lastSelectorChar) tokenish]
whileFalse: [lastSelectorChar _ lastSelectorChar - 1].
aFileStream printMethod: (string copyFrom: 1 to: lastSelectorChar)
withBody: (string copyFrom: lastSelectorChar + 1 to: string size)]!
printOutOn: aFileStream
aFileStream printClassDefinitionFor: self name from: self definitionAsTable.
aFileStream printClassComment: self comment.
self organization categories do:
[:heading |
aFileStream anotherProtocol.
self printOutCategory: heading on: aFileStream]! !
!Metaclass methodsFor: 'accessing'!
category
^thisClass category! !
!Class methodsFor: 'fileIn-Out'!
printOut
LatexStream for: self name do:
[:fileStream |
Transcript cr; show: 'Printing out ' , self name.
fileStream beginClass.
self printOutOn: fileStream.
fileStream endClass]!
printOutOn: aFileStream
super printOutOn: aFileStream.
self class nonTrivial
ifTrue:
[aFileStream anotherClass.
self class printOutOn: aFileStream]! !